﻿#include "btNetHandler.h"
#include "pthread.h"
#include "btNetStruct.h"
#include "btNetDefine.h"
#include "btSceneManager.h"
#include "btSceneBase.h"
#include "btMapObjectMgr.h"
#ifdef WIN32
#include "win32/FOLog.h"
#endif
//三个线程,connect在成功之后,会自动退出,同时创建其他两个线程
pthread_t t_connect;
pthread_t t_recv;
pthread_t t_send;
bool g_exitRecvThread = false;

CNetHandler* CNetHandler::sharedNetHandler()
{
	static CNetHandler pNetHandler;
	return &pNetHandler;
}

CNetHandler::CNetHandler()
:m_pSocket(NULL),
m_step(STEP_NR),
m_bIsConnected(false),
m_connectErrorTime(0)
, m_nKeepAlivePingSendCount(0)
,m_bIfUpdateEventQueue(true)
,m_sSysTime("")
//,m_pHelloworld(NULL)
{
	
}
CNetHandler::~CNetHandler()
{
}
/******************************************************************
 //funcName:ReleaseSocket
 
 //date:2013/3/13 22:23
 
 //desc:清空socket
 
 //param:
 
 //ret value:
 
 //author:butcher
 ******************************************************************/
void CNetHandler::ReleaseSocket()
{
	if(m_pSocket){
		CCLOG("nethandler releaseSocket and exit recv thread");
		m_pSocket->Close();
		g_exitRecvThread = true;
		pthread_join(t_recv,NULL);
		m_pSocket->Clean();
		CC_SAFE_DELETE(m_pSocket);
		//不需要在里面设置状态
		//m_step = STEP_NR;
		m_bIsConnected = false;
	}
}
/******************************************************************
 //funcName:resetSocket
 
 //date:2013/3/16 22:40
 
 //desc:重置socket,其实就是设置一下step状态,init的时候会进行socket的初始化等等
 
 //param:
 
 //ret value:
 
 //author:butcher
 ******************************************************************/
void CNetHandler::resetSocket()
{
	CCLOG("reset socket");
	m_step = STEP_INIT;
}
bool CNetHandler::init()
{
	resetSocket();
	onEnter();
	onEnterTransitionDidFinish();
	scheduleUpdate();
	return true;
}
void CNetHandler::Quit()
{
	ReleaseSocket();
	this->unscheduleUpdate();
	std::list<_netEventStructBase*>::iterator it = m_netEventQueue.begin();
	for(; it != m_netEventQueue.end(); it++){
		CC_SAFE_DELETE(*it);
	}
	m_netEventQueue.clear();
}
void CNetHandler::update(float dt)
{
    if (!m_bIfUpdateEventQueue) {
        return;
    }
	updateEventQueue(dt);
	switch(m_step){
		case STEP_INIT:
			if(m_pSocket == NULL){
				m_bIsConnected = false;
				m_pSocket = new CSocket();
				m_pSocket->Init();
				m_pSocket->Create(AF_INET,SOCK_STREAM,0);
			}
			CreateConnectThread();
			m_step = STEP_CONNECT;
			break;
		case STEP_CONNECT:
			break;
		case STEP_MAIN:
			break;
	}
}
/******************************************************************
 //funcName:updateEventQueue
 
 //date:2013/3/14 20:49
 
 //desc:对消息队列进行处理,分发
 注意mutex,可能会在recv线程中也会对队列进行操作
 //param:
 
 //ret value:
 
 //author:butcher
 ******************************************************************/
void CNetHandler::updateEventQueue(float dt)
{
	LockMutex();
	//每帧处理一个事件,不再同一帧处理两个事件
	if(!m_netEventQueue.empty()){
		_netEventStructBase* pEvent = m_netEventQueue.front();
        m_nKeepAlivePingSendCount = 0;//只要收到消息就为0
        pEvent->execute();
		CC_SAFE_DELETE(pEvent);
		m_netEventQueue.pop_front();
	}
	UnLockMutex();
}
/******************************************************************
 //funcName:addEvent
 
 //date:2013/3/14 20:49
 
 //desc:加入一个事件对象
 注意mutex,可能会在updaetEventQueue中队列会被操作
 
 //param:
 
 //ret value:
 
 //author:butcher
 ******************************************************************/
void CNetHandler::addEvent(_netEventStructBase*pEvent)
{
	if(pEvent == NULL)
		return;
	bool bIsErrorEvent = pEvent->m_eventType == NET_EVENT_SEND_ERROR;// || pEvent->m_eventType == NET_EVENT_RECV_ERROR;
	// 如果要加入的事件是sendError/recvError,做个判断是否自动重连接次数已经达到,如果达到可以弹出对话框,否则继续重连接 [2013/6/19 14:40 butcher]
	if(bIsErrorEvent){
		if(getConnectErrorTime() < RETRY_CONNECT_TOTAL_TIME_BEFORE_HINT){
			//清除队列中网络错误的事件
			std::list<_netEventStructBase*>::iterator it = m_netEventQueue.begin();
			for(; it != m_netEventQueue.end();){
				_netEventStructBase* pTempEvent = m_netEventQueue.front();
				if(pTempEvent->m_eventType == NET_EVENT_SEND_ERROR/* || pTempEvent->m_eventType == NET_EVENT_RECV_ERROR*/){
					CC_SAFE_DELETE(pTempEvent);
					m_netEventQueue.erase(it++);
				}else{
					it++;
				}
			}
			reconnet();
			return;//直接返回,不加入
		}else{
			m_connectErrorTime = 0;
		}
	}
	//如果网络没有连接上,命令都暂时不执行,除了错误的命令可以执行
	if(!isConnected() && !bIsErrorEvent)
		return;
	CCAssert(pEvent,"");
	LockMutex();
	m_netEventQueue.push_back(pEvent);
	UnLockMutex();
}
/******************************************************************
 //funcName:OnConnectFinished
 
 //date:2013/3/13 20:58
 
 //desc:连接服务器有个结果之后
 
 //param:
 ret:conncect的返回值
 
 //ret value:
 
 //author:butcher
 ******************************************************************/
void CNetHandler::OnConnectFinished(int ret,int ecode)
{
	if(ret != SOCKET_ERROR){
		m_step = STEP_MAIN;
		CreateRecvThread();
		m_bIsConnected = true;
		m_connectErrorTime = 0;
		CSceneBase* pScene = CSceneManager::GetSingletonPtr()->getCurrentScene();
		CCAssert(pScene,"");
		if(pScene)
			pScene->onConnectToServerSucc();
	}else{
		m_bIsConnected = false;
		m_connectErrorTime++;
		CCLOG("reconnect time:%d",m_connectErrorTime);
		_netSendError* pErrorEvent = _netSendError::create(0,ecode);
		addEvent(pErrorEvent);
	}
}
void* connectProc(void* pArg)
{
	CNetHandler* pNetLayer = (CNetHandler*)pArg;
	int ret = SOCKET_ERROR;
	int ecode = 0;
	CSocket*pSocket = pNetLayer->GetSocket();
	if(pNetLayer && pSocket){
		ret = pNetLayer->GetSocket()->Connect(SERVER_IP,SERVER_PORT,ecode);
	}
	pNetLayer->OnConnectFinished(ret,ecode);
	CCLOG("connect thread exit");
	return NULL;
}
/******************************************************************
 //funcName:CreateConnectThread
 
 //date:2013/3/13 20:50
 
 //desc:创建连接线程
 
 //param:
 
 //ret value:
 
 //author:butcher
 ******************************************************************/
int CNetHandler::CreateConnectThread()
{
	int errCode = 0;
	do{
		pthread_attr_t tAttr;
		errCode = pthread_attr_init(&tAttr);
		CC_BREAK_IF(errCode!=0);
		errCode = pthread_attr_setdetachstate(&tAttr, PTHREAD_CREATE_DETACHED);
		if (errCode!=0) {
			pthread_attr_destroy(&tAttr);
			break;
		}
		errCode = pthread_create(&t_connect, &tAttr, connectProc, this);
	}while (0);
	return errCode;
}
/******************************************************************
//funcName:reconnet	

//date:2013/6/12 17:50

//desc:重新连接网络,供外部调用  

//param:

//ret value:

//author:butcher
******************************************************************/
void CNetHandler::reconnet()
{
	ReleaseSocket();
	m_step = STEP_INIT;
}
/******************************************************************
//funcName:recvProc	

//date:2013/3/13 21:01

//desc:接收数据  

//param:

	bsd中sleep的替代方法:

	void * thr_fn(void * arg)   
	{  
	struct timeval now;  
	struct timespec outtime;  
	pthread_mutex_lock(&mutex);  
	while (flag) {  
	printf("*****\n");  
	gettimeofday(&now, NULL);  
	outtime.tv_sec = now.tv_sec + 5;  
	outtime.tv_nsec = now.tv_usec * 1000;  
	pthread_cond_timedwait(&cond, &mutex, &outtime);  
	}  
	pthread_mutex_unlock(&mutex);  
	printf("cond thread exit\n");  
	}  

	int main(void)   
	{  
	pthread_mutex_init(&mutex, NULL);  
	pthread_cond_init(&cond, NULL);  
	if (0 != pthread_create(&thread, NULL, thr_fn, NULL)) {  
	printf("error when create pthread,%d\n", errno);  
	return 1;  
	}  
	char c ;  
	while ((c = getchar()) != 'q');  
	printf("Now terminate the thread!\n");  

	pthread_mutex_lock(&mutex);  
	flag = 0;  
	pthread_cond_signal(&cond);  
	pthread_mutex_unlock(&mutex);  
	printf("Wait for thread to exit\n");  
	pthread_join(thread, NULL);  
	printf("Bye\n");  
	return 0;  
	}  

//ret value:

//author:butcher
******************************************************************/
void* recvProc(void* pArg)
{
	CNetHandler* pNetLayer = (CNetHandler*)pArg;
	if(pNetLayer){
		while(!g_exitRecvThread && pNetLayer->GetSocket()){
			CCLOG("socket recv waing");
            //#ifdef WIN32
            //			::Sleep(50);
            //#else
            //			sleep(0.05f);//休眠
            //#endif
			char *buf = NULL;
			int errorCode;
			int len = pNetLayer->GetSocket()->Recv(
                                                   &buf,
                                                   0,
                                                   errorCode);
			// 游戏退出的时候的对应 [2013/3/15 12:15 butcher]
			if(g_exitRecvThread){
				CCLOG("recv thread exit");
				CC_SAFE_DELETE_ARRAY(buf);
				return NULL;
			}
			pNetLayer->parseNetRecvData(buf,len,errorCode);
			CC_SAFE_DELETE_ARRAY(buf);
			CCLOG("socket recv waing end");
		}
	}	
	CCLOG("recv thread exit");
	return NULL;
}
int CNetHandler::CreateRecvThread()
{
	int errCode = 0;
	do{
		pthread_attr_t tAttr;
		errCode = pthread_attr_init(&tAttr);
		CC_BREAK_IF(errCode!=0);
        errCode = pthread_attr_setdetachstate(&tAttr, PTHREAD_CREATE_DETACHED);
		if (errCode!=0) {
			pthread_attr_destroy(&tAttr);
			break;
		}
		g_exitRecvThread = false;
		errCode = pthread_create(&t_connect, &tAttr, recvProc, this);
#ifdef USE_LOG
		CFOLog::getSingletonPtr()->addString("nethandler:create recv thread succ");
#endif
		CCLOG("CNetHandler create recv thread,code:%d",errCode);
	}while (0); 
	return errCode; 
}/******************************************************************
 //funcName:sendProc
 
 //date:2013/3/13 21:02
 
 //desc:发送数据线程
 暂时不用,直接调用对应的发送数据函数
 //param:
 
 //ret value:
 
 //author:butcher
 ******************************************************************/
//void* sendProc(void* pArg)
//{
//	CNetHandler* pNetLayer = (CNetHandler*)pArg;
//	if(pNetLayer && pNetLayer->GetSocket()){
//
//	}
//	return NULL;
//}
//int CNetHandler::CreateSendThread()
//{
//	int errCode = 0;
//	do{
//		pthread_attr_t tAttr;
//		errCode = pthread_attr_init(&tAttr);
//		CC_BREAK_IF(errCode!=0) ;
//			errCode = pthread_attr_setdetachstate(&tAttr, PTHREAD_CREATE_DETACHED);
//		if (errCode!=0) {
//			pthread_attr_destroy(&tAttr);
//			break;
//		}
//		errCode = pthread_create(&t_connect, &tAttr, sendProc, this);
//	}while (0);
//	return errCode;
//}
//////////////////////////////////////////////////////////////////////////
/******************************************************************
//funcName:onNetError	

//date:2013/6/12 17:40

//desc:当网络出现错误的时候的通用处理方法,现在就是直接断掉,给个提示框,是否要重新连接,就再说吧  

//param:

//ret value:

//author:butcher
******************************************************************/
void CNetHandler::onNetError(int len,int errorcode)
{
	// 直接网络断开,然后尝试重新连接 [2013/6/12 17:39 butcher]
	ReleaseSocket();
	_netSendError* pErrorEvent = _netSendError::create(len,errorcode);
	addEvent(pErrorEvent);
	CCLOG("parseNetRecvData error:code:%d,geterror:%d",len,errorcode);
}
/******************************************************************
//funcName:parseNetRecvData	

//date:2013/3/14 15:17

//desc:对接收到的数据进行解析,同时放入事件队列中  

//param:
	buflen:总共读取到的数据

	成功执行时，返回接收到的字节数。另一端已关闭则返回0。失败返回-1，errno被设为以下的某个值   
	返回值<0时并且(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)的情况下认为连接是正常的，继续接收。
	EAGAIN：套接字已标记为非阻塞，而接收操作被阻塞或者接收超时
	EBADF：sock不是有效的描述词
	ECONNREFUSE：远程主机阻绝网络连接
	EFAULT：内存空间访问出错
	EINTR：操作被信号中断
	EINVAL：参数无效
	ENOMEM：内存不足
	ENOTCONN：与面向连接关联的套接字尚未被连接上
	ENOTSOCK：sock索引的不是套接字

	当返回值是0时，为正常关闭连接；

//ret value:

//author:butcher
******************************************************************/
void CNetHandler::parseNetRecvData(const char* pBuffer,int buflen,int errorCode)
{
	if(m_pSocket == NULL)
		return;
	//和服务器的连接断掉了??或者遇到错误
	if(buflen <= 0){
		if(!m_pSocket->IsCoutinueError(errorCode)){//准备断开连接
			onNetError(buflen,errorCode);
		}
	}else{
		// decode [2013/3/19 16:37 butcher]
		//std::string tempstr = pBuffer;
		std::string tempstr = CGameUtils::DecodeURL(pBuffer);
		tempstr = CGameUtils::replace_all(tempstr,"%20"," ");
		CCLOG("recv buf:%s,len:%d",tempstr.c_str(),tempstr.length());
#ifdef WIN32
		CFOLog::getSingletonPtr()->addString("recv buf:%s,len:%d",tempstr.c_str(),tempstr.length());
#endif
		//CCFileUtils::sharedFileUtils()->
		// 读取的应该是一条完整的命令 [2013/3/24 1:21 butcher]
		//最后一个感叹号要去掉
        //COCwwj
		//std::string oneCommandStr = tempstr;//tempstr.substr(0,tempstr.length()-1);
		_netEventStructBase* pEventBase = parseOneRecvCommand(tempstr);
		if(pEventBase){
			addEvent(pEventBase);
		}
		//可能一个buffer中有多条命令,进行while解析
		/*while(tempstr.length() > 0){
         int pos = tempstr.find('!');
         CCAssert(pos != -1,"");
         std::string oneCommandStr = tempstr.substr(0,pos);
         _netEventStructBase* pEventBase = parseOneRecvCommand(oneCommandStr);
         if(pEventBase){
         addEvent(pEventBase);
         }
         tempstr = tempstr.substr(pos+1,-1);
         }*/
	}
}
/******************************************************************
 //funcName:parseOneRecvCommand
 
 //date:2013/3/14 15:33
 
 //desc:对一条完整的指令进行解析,
 
 //param:commandstr(可以直接修改,不作为out):命令
 
 //ret value:事件对象
 
 //author:butcher
 ******************************************************************/
_netEventStructBase* CNetHandler::parseOneRecvCommand(std::string& commandstr)
{
	std::string headname = _netRecvEventBase::truncateCommandHeaderStr(commandstr);
	_netRecvEventBase* pRecvEvent = _netRecvEventBase::create(headname,commandstr);
	return pRecvEvent;
}

//////////////////////////////////////////////////////////////////////////
//发送事件
/******************************************************************
 //funcName:SendEventCreateUser
 
 //date:2013/3/15 13:28
 
 //desc:发送事件
 
 在其中,就要对一些名字等等做Encode处理
 
 //param:
 
 //ret value:
 
 //author:butcher
 ******************************************************************/
bool CNetHandler::SendEventCreateUser(const std::string& gameCenterId,const std::string& username)
{
	_netSendEventCreateUser eventinf;
	eventinf.m_eventType = NET_EVENT_CREATE_USER;
	eventinf.m_gameCenterId = CGameUtils::EncodeURL(gameCenterId);
	eventinf.m_userName = CGameUtils::EncodeURL(username);
	return eventinf.execute();
}
bool CNetHandler::SendEventLogIn(int m_userID)
{
	_netSendEventLogIn eventinf;
	eventinf.m_eventType = NET_EVENT_LOGIN;
	eventinf.m_userID = m_userID;
    
	//// 太糟糕的设计了 [2013/4/16 22:38 butcher]
	//std::string sendstr = eventinf.generateSendStr();
	//eventinf.SendHeadCmd(sendstr.length());
    
	return eventinf.execute();
}
bool CNetHandler::SendEventLogOut()
{
	_netSendEventLogOut eventinf;
	eventinf.m_eventType = NET_EVENT_LOGOUT;
	//eventinf.m_userID = m_userID;
	eventinf.m_userInf = MY_BASIC_INF;
	return eventinf.execute();
}
bool CNetHandler::SendEventGetPlayerMapInfo(int m_userID,int nFirstLoad)
{
	_netSendEventGetPlayerMapInfo eventinf;
	eventinf.m_eventType = NET_EVENT_GET_PLAYER_MAP;
	eventinf.m_userID = m_userID;
    eventinf.m_nFirstLoad = nFirstLoad;
	return eventinf.execute();
}
//bool CNetHandler::SendEventSavePlayerMapInfo(int m_userID)
//{
//	_netSendEventSavePlayerMapInfo eventinf;
//	eventinf.m_eventType = NET_EVENT_SAVE_PLAYER_MAP;
//	eventinf.m_userID = m_userID;
//	return eventinf.execute();
//}
//灵石数量的改变或者查询[2013/06/05 ZZB]
bool CNetHandler::SendEventChangeLingshiCount(int m_userID, int LingshiNr)
{
    _netSendEventChangeLingshiCount eventinf;
	eventinf.m_eventType = NET_EVENT_CHANGE_LINGSHI_COUNT;
	eventinf.m_userID = m_userID;
	eventinf.m_nChangeCount = LingshiNr;
	return eventinf.execute();
}
//创建用户名发送消息
bool CNetHandler::SendEventCreateUserName(int iUserID, const std::string& strUserName)
{
    _netSendEventUserName eventinf;
    eventinf.m_eventType = NET_EVENT_NAME;
    eventinf.m_iUserID = iUserID;
    eventinf.m_strUserName = strUserName;
    return eventinf.execute();
}

//COC wwj
bool CNetHandler::SendEventSavePlayerMapInfo(int m_userID,const std::string& mapData)
{
	_netSendEventSavePlayerMapInfo eventinf;
	eventinf.m_eventType = NET_EVENT_SAVE_PLAYER_MAP;
	eventinf.m_userID = m_userID;
	eventinf.m_mapdata = mapData;
	return eventinf.execute();
}
//
bool CNetHandler::SendEventShowFriendsList(int m_userID)
{
	_netSendEventShowFriendsList eventinf;
	eventinf.m_eventType = NET_EVENT_SHOW_FRIEND_LIST;
	eventinf.m_userID = m_userID;
	return eventinf.execute();
}
bool CNetHandler::SendEventQueryUsers(const std::string& m_userName)
{
	_netSendEventQueryUsers eventinf;
	eventinf.m_eventType = NET_EVENT_QUERY_USERS;
	eventinf.m_userName = CGameUtils::EncodeURL(m_userName);
	return eventinf.execute();
}
bool CNetHandler::SendEventAddFriend(int m_userID,int m_friendID)
{
	_netSendEventAddFriend eventinf;
	eventinf.m_eventType = NET_EVENT_ADD_FRIEND;
	eventinf.m_userID = m_userID;
	eventinf.m_friendID = m_friendID;
	return eventinf.execute();
}
bool CNetHandler::SendEventAcceptAddFriend(int m_userID,int m_friendID)
{
	_netSendEventAcceptAddFriend eventinf;
	eventinf.m_eventType = NET_EVENT_ACCEPTADDFRIEND;
	eventinf.m_userID = m_userID;
	eventinf.m_friendID = m_friendID;
	return eventinf.execute();
}
bool CNetHandler::SendEventQueryOfflineAddFriendMsg(int m_userID)
{
	_netSendEventQueryOfflineAddFriendMsg eventinf;
	eventinf.m_eventType = NET_EVENT_QUERYOFFLINEADDFRIENDMSG;
	eventinf.m_userID = m_userID;
	return eventinf.execute();
}
bool CNetHandler::SendEventDeleteFriend(int m_userID,int m_friendID)
{
	_netSendEventDeleteFriend eventinf;
	eventinf.m_eventType = NET_EVENT_DELETE_FRIEND;
	eventinf.m_userID = m_userID;
	eventinf.m_friendID = m_friendID;
	return eventinf.execute();
}
bool CNetHandler::SendEventSendFriendMsg(int m_userID,int m_friendID,const std::string& msg)
{
	_netSendEventSendFriendMsg eventinf;
	eventinf.m_eventType = NET_EVENT_SEND_FRIEND_MSG;
	eventinf.m_userID = m_userID;
	eventinf.m_friendID = m_friendID;
	eventinf.m_msg = CGameUtils::EncodeURL(msg);
	return eventinf.execute();
}
//bool CNetHandler::SendEventVisit(int m_visitUserID)
//{
//	_netSendEventVisit eventinf;
//	eventinf.m_eventType = NET_EVENT_VISIT;
//	eventinf.m_visitUserID = m_visitUserID;
//	return eventinf.execute();
//}
//
bool CNetHandler::SendEventQueryTeam(void)
{
	_netSendEventQueryTeam eventinf;
	eventinf.m_eventType = NET_EVENT_QUERY_TEAM;
    eventinf.m_userID = MY_BASIC_INF.user_id;
	return eventinf.execute();
}
bool CNetHandler::SendEventAddTeam(int m_userID,int m_teamID,int m_targetID,int nMaxLevelHeroType)
{
	_netSendEventAddTeam eventinf;
	eventinf.m_eventType = NET_EVENT_ADD_TEAM;
	eventinf.m_userID = m_userID;
	eventinf.m_teamID = m_teamID;
	eventinf.m_targetId = m_targetID;
    eventinf.m_nMaxLevelHeroType = nMaxLevelHeroType;
	return eventinf.execute();
}
bool CNetHandler::SendEventCreateTeam(int m_userID,int m_teamGoalID,int nMaxLevelHeroType)
{
	_netSendEventCreateTeam eventinf;
	eventinf.m_eventType = NET_EVENT_CREATE_TEAM;
	eventinf.m_userID = m_userID;
	eventinf.m_teamGoalID = m_teamGoalID;
    eventinf.m_nMaxLevelHeroType = nMaxLevelHeroType;
	return eventinf.execute();
}
bool CNetHandler::SendEventLeaveTeam(int m_userID,int m_teamID)
{
	_netSendEventLeaveTeam eventinf;
	eventinf.m_eventType = NET_EVENT_LEAVE_TEAM;
	eventinf.m_userID = m_userID;
	eventinf.m_teamID = m_teamID;
	return eventinf.execute();
}
bool CNetHandler::SendEventDeleteUser(int m_playerID,int teamid)
{
	_netSendEventDeleteUser eventinf;
	eventinf.m_eventType = NET_EVENT_DELETE_TEAM_USER;
	eventinf.m_playerID = m_playerID;
	eventinf.m_teamID = teamid;
	return eventinf.execute();
}
bool CNetHandler::SendEventSendTeamMsg(
									   int m_userID,
									   int m_teamID,
									   const std::string& msg)
{
	_netSendEventSendTeamMsg eventinf;
	eventinf.m_eventType = NET_EVENT_SEND_TEAM_MSG;
	eventinf.m_userID = m_userID;
	eventinf.m_teamID = m_teamID;
	eventinf.m_msg = CGameUtils::EncodeURL(msg);
	return eventinf.execute();
}
bool CNetHandler::SendEventInviteToTeam(int m_teamID,int m_userID,int m_invitedID,const std::string& username)
{
	_netSendEventInviteToTeam eventinf;
	eventinf.m_eventType = NET_EVENT_INVITE_TO_TEAM;
	eventinf.m_userID = m_userID;
	eventinf.m_teamID = m_teamID;
	eventinf.m_username = CGameUtils::EncodeURL(username);
	eventinf.m_invitedPlayerID = m_invitedID;
	return eventinf.execute();
}
//获取服务器捐兵消息ZZB
bool CNetHandler::SendEventGetDonatorDonationMessage(int userID)
{
    _netSendEventDonatorDonationMessage eventinf;
    eventinf.m_eventType = NET_EVENT_GET_UNION_SOLDIERS;
    eventinf.m_userID = userID;
	return eventinf.execute();
}
bool CNetHandler::SendEventDisMissTeam(int m_teamID,int userID)
{
	_netSendEventDisMissTeam eventinf;
	eventinf.m_eventType = NET_EVENT_DISMISS_TEAM;
	eventinf.m_teamID = m_teamID;
	eventinf.m_userID = userID;
	return eventinf.execute();
}
bool CNetHandler::SendEventAcceptEnterTeam(int m_teamID,int userID,int nMaxLevelHeroType)
{
	_netSendEventAcceptEnterTeam eventinf;
	eventinf.m_eventType = NET_EVENT_ACCEPTENTERTEAM;
	eventinf.m_teamID = m_teamID;
	eventinf.m_userID = userID;
    eventinf.m_nMaxLevelHeroType = nMaxLevelHeroType;
	return eventinf.execute();
}
bool CNetHandler::SendEventRefuseInviteToTeam(int m_teamID,int userID)
{
	_netSendEventRefuseInviteToTeam eventinf;
	eventinf.m_eventType = NET_EVENT_REFUSEINVITETOTEAM;
	eventinf.m_teamID = m_teamID;
	eventinf.m_userID = userID;
	return eventinf.execute();
}
bool CNetHandler::SendEventQueryMyTeam(int userID)
{
	_netSendEventQueryMyTeam eventinf;
	eventinf.m_eventType = NET_EVENT_QUERYMYTEAM;
	eventinf.m_userID = userID;
	return eventinf.execute();
}
bool CNetHandler::SendEventShowOnlinePlayers(int userID)
{
	_netSendEventShowOnlinePlayers eventinf;
	eventinf.m_eventType = NET_EVENT_SHOWONLINEPLAYERS;
	eventinf.m_userID = userID;
	return eventinf.execute();
}
bool CNetHandler::SendEventShowOnlineFriends(int userID)
{
	_netSendEventShowOnlineFriends eventinf;
	eventinf.m_eventType = NET_EVENT_SHOWONLINEFRIENDS;
	eventinf.m_userID = userID;
	return eventinf.execute();
}
bool CNetHandler::SendEventShowOnlineClanPlayers(int userID)
{
	_netSendEventShowOnlineClanPlayers eventinf;
	eventinf.m_eventType = NET_EVENT_SHOWONLINECLANPLAYERS;
	eventinf.m_userID = userID;
	return eventinf.execute();
}
//
bool CNetHandler::SendEventQueryUnions(const std::string& m_unionName)
{
	_netSendEventQueryUnions eventinf;
	eventinf.m_eventType = NET_EVENT_QUERYUNIONS;
	eventinf.m_unionName = CGameUtils::EncodeURL(m_unionName);
	return eventinf.execute();
}
bool CNetHandler::SendEventApplyIntoUnion(int m_unionID,int m_userID)
{
	_netSendEventApplyIntoUnion eventinf;
	eventinf.m_eventType = NET_EVENT_APPLYINTOUNION;
	eventinf.m_userID = m_userID;
	eventinf.m_unionID = m_unionID;
	return eventinf.execute();
}
//CreateUnion?userId=26&unionName=union4&unionIcan=0&desc=testdes&type=0&score=0
bool CNetHandler::SendEventCreateUnion(
                                       int m_userID,
                                       const std::string& m_unionName,
                                       int icon,
                                       const std::string& m_unionDesc,
                                       int m_acceptMemberType,
                                       int m_acceptJoinMinScore
                                       )
{
	_netSendEventCreateUnion eventinf;
	eventinf.m_eventType = NET_EVENT_CREATEUNION;
	eventinf.m_userID = m_userID;
	eventinf.m_unionName = CGameUtils::EncodeURL(m_unionName);
	eventinf.m_unionIcon = icon;
	eventinf.m_unionDesc = CGameUtils::EncodeURL(m_unionDesc);
	eventinf.m_acceptMemberType = m_acceptMemberType;
	eventinf.m_acceptJoinMinScore = m_acceptJoinMinScore;
	return eventinf.execute();
}
bool CNetHandler::SendEventShowUnion(int m_unionID)
{
	_netSendEventShowUnion eventinf;
	eventinf.m_eventType = NET_EVENT_SHOWUNION;
	eventinf.m_unionID = m_unionID;
	return eventinf.execute();
}
bool CNetHandler::SendEventSendUnionMsg(
										int m_unionID,
										int m_userID,
										const std::string& msg)
{
	_netSendEventSendUnionMsg eventinf;
	eventinf.m_eventType = NET_EVENT_SENDUNIONMSG;
	eventinf.m_userID = m_userID;
	eventinf.m_unionID = m_unionID;
	eventinf.m_msg = CGameUtils::EncodeURL(msg);
	return eventinf.execute();
}
bool CNetHandler::SendEventDismissUnion(int m_userID)
{
	_netSendEventDismissUnion eventinf;
	eventinf.m_eventType = NET_EVENT_DISMISSUNION;
	eventinf.m_userID = m_userID;
	return eventinf.execute();
}
bool CNetHandler::SendEventQueryTopUnions(void)
{
	_netSendEventQueryTopUnions eventinf;
	eventinf.m_eventType = NET_EVENT_QUERYTOPUNIONS;
	return eventinf.execute();
}
bool CNetHandler::SendEventLeaveUnion(int m_userID)
{
	_netSendEventLeaveUnion eventinf;
	eventinf.m_eventType = NET_EVENT_LEAVEUNION;
	eventinf.m_userID = m_userID;
	return eventinf.execute();
}
bool CNetHandler::SendEventQueryUnionMsg(int m_userID,int m_time)
{
	_netSendEventQueryUnionMsg eventinf;
	eventinf.m_eventType = NET_EVENT_QUERYUNIONMSG;
	eventinf.m_userID = m_userID;
	//eventinf.m_time = m_time;
	eventinf.m_time = "";
	return eventinf.execute();
}
bool CNetHandler::SendEventDeleteUnionMember(int leaderID,int m_userID)
{
	_netSendEventDeleteUnionMember eventinf;
	eventinf.m_eventType = NET_EVENT_DELETEUNIONMEMBER;
	eventinf.m_leaderID = leaderID;
	eventinf.m_userID = m_userID;
	return eventinf.execute();
}
bool CNetHandler::SendEventBroadUnionMsg(
                                         int m_userID,
                                         int msg_type)
{
	_netSendEventBroadUnionMsg eventinf;
	eventinf.m_eventType = NET_EVENT_BROADUNIONMSG;
	eventinf.m_userID = m_userID;
	eventinf.m_msgType = msg_type;
	return eventinf.execute();
}
bool CNetHandler::SendEventModifyUnionMemberRole(
                                                 const _oneUnionMemberModifyInf& inf)
{
	_netSendEventModifyUnionMemberRole  eventinf;
	eventinf.m_eventType = NET_EVENT_MODIFYONEUNIONMEMBER;
	eventinf.inf = inf;
	return eventinf.execute();
}
bool CNetHandler::SendEventBatchModifyUnionMembers(
	int modifyuserid,//  [2013/7/4 17:04 butcher]
	const std::vector<_oneUnionMemberModifyInf>& infvec)
{
	_netSendEventBatchModifyUnionMembers  eventinf;
	eventinf.m_eventType = NET_EVENT_BATCHMODIFYUNIONMEMBERS;
	eventinf.m_modifyuserid = modifyuserid;
	eventinf.m_infVec = infvec;
	return eventinf.execute();
}
bool CNetHandler::SendEventCorAttack(int teamid, int selectMapID)
{
	_netSendEventCorAttack  eventinf;
	eventinf.m_eventType = NET_EVENT_COMMON_BUILD_CORATTACK;
	eventinf.m_teamID = teamid;
    eventinf.m_mapID = selectMapID;
	return eventinf.execute();
}

bool CNetHandler::SendEventGrabResources(int id, std::vector<int>& idVec, int* headArr)
{
    _netSendEventGrabResources eventinf;
    eventinf.m_eventType = NET_EVENT_GRAB_RESOURCES;
    eventinf.sendUseId = id;
    for (int i = 0; i < idVec.size(); ++i)
    {
        _netSendEventGrabResources::inf info;
        info.m_userID = idVec[i];
        info.m_coinNum = *(headArr + i * 2);
        info.m_foodNum = *(headArr + i * 2 + 1);
        eventinf.infVec.push_back(info);
    }
    return eventinf.execute();
}

bool CNetHandler::SendEventCorBuild(int teamid)
{
	_netSendEventCorBuild  eventinf;
	eventinf.m_eventType = NET_EVENT_COMMON_BUILD_CORBUILD;
	eventinf.m_teamID = teamid;
	return eventinf.execute();
}
bool CNetHandler::SendEventStartBuilding(int userid,int teamid,const std::string& mapData)
{
	_netSendEventStartBuilding  eventinf;
	eventinf.m_eventType = NET_EVENT_COMMON_BUILD_START_BUILDING;
	eventinf.m_userID = userid;
	eventinf.m_teamID = teamid;
	eventinf.m_mapdata = mapData;
	return eventinf.execute();
}
bool CNetHandler::SendEventGetTeamMapInfo(int userid,int teamid)
{
	_netSendEventGetTeamMapInfo  eventinf;
	eventinf.m_eventType = NET_EVENT_COMMON_BUILD_GET_TEAM_MAP;
	eventinf.m_userID = userid;
	eventinf.m_teamID = teamid;
	return eventinf.execute();
}
bool CNetHandler::SendEventBuildingBuild(
                                         int userid,
                                         int buildingtype,
                                         int usertilenr,
                                         int tilex,
                                         int tiley)
{
	_netSendEventBuildingBuild  eventinf;
	eventinf.m_eventType = NET_EVENT_BUILDING_BUILD;
	eventinf.m_userID = userid;
	eventinf.m_buildingType = buildingtype;
	eventinf.m_buildingUsedTileNr = usertilenr;
	eventinf.m_tileX = tilex;
	eventinf.m_tileY = tiley;
	
	return eventinf.execute();
}
bool CNetHandler::SendEventBuildingBuildFinished(
                                                 int userid,
                                                 int tileid,
                                                 int buildingtype)
{
	_netSendEventBuildingBuildFinished  eventinf;
	eventinf.m_eventType = NET_EVENT_BUILDING_BUILD_FINISHED;
	eventinf.m_userID = userid;
	eventinf.m_buildingTileID = tileid;
	eventinf.m_buildingType = buildingtype;
    
	return eventinf.execute();
}
bool CNetHandler::SendEventBuildingMoveEnd(
                                           int userid,
                                           int tileid,
                                           int buildingtype,
                                           int usertilenr,
                                           int tilex,
                                           int tiley,
                                           int formertilex,
                                           int formertiley)
{
	_netSendEventBuildingMoveEnd  eventinf;
	eventinf.m_eventType = NET_EVENT_BUILDING_MOVE_END;
	eventinf.m_userID = userid;
	eventinf.m_buildingTileID = tileid;
	eventinf.m_buildingType = buildingtype;
	eventinf.m_buildingUsedTileNr = usertilenr;
	eventinf.m_tileX = tilex;
	eventinf.m_tileY = tiley;
	eventinf.m_formerTileX = formertilex;
	eventinf.m_formerTileY = formertiley;
    
	return eventinf.execute();
}
bool CNetHandler::SendEventBuildingUpgrade(
                                           int userid,
                                           int tileid,
                                           int buildingtype,
                                           int nowlevel)
{
	_netSendEventBuildingUpgrade  eventinf;
	eventinf.m_eventType = NET_EVENT_BUILDING_UPGRADE;
	eventinf.m_userID = userid;
	eventinf.m_buildingTileID = tileid;
	eventinf.m_buildingType = buildingtype;
	eventinf.m_nowlevel = nowlevel;

	return eventinf.execute();
}
bool CNetHandler::SendEventBuildingUpgradeFinished(int userid,int tileid,int buildingType,int nowlevel)
{
	_netSendEventBuildingUpgradeFinished  eventinf;
	eventinf.m_eventType = NET_EVENT_BUILDING_UPGRADE_FINISHED;
	eventinf.m_userID = userid;
	eventinf.m_buildingTileID = tileid;
	eventinf.m_buildingType = buildingType;
	eventinf.m_nowlevel = nowlevel;

	return eventinf.execute();
}
bool CNetHandler::SendEventBuildingDecBlood(int userid,int tileid,int buildingType,float nowblood)
{
	_netSendEventBuildingDecBlood  eventinf;
	eventinf.m_eventType = NET_EVENT_BUILDING_DEC_BLOOD;
	eventinf.m_userID = userid;
	eventinf.m_buildingTileID = tileid;
	eventinf.m_buildingType = buildingType;
	eventinf.m_nowblood = nowblood;

	return eventinf.execute();
}
bool CNetHandler::SendEventMagicStart(int userid,CCPoint& pos,int tilex,int tiley)
{
	_netSendEventMagicStart  eventinf;
	eventinf.m_eventType = NET_EVENT_MAGIC_START;
	eventinf.m_userID = userid;
	eventinf.pos = pos;
	eventinf.tilex = tilex;
	eventinf.tiley = tiley;
	return eventinf.execute();
}

bool CNetHandler::SendEventSoldierMovetoAttack(int userid, const std::vector<_oneSoldierAttackMoveInf>& infvec)
{
	_netSendEventSoldierMovetoAttack  eventinf;
	eventinf.m_eventType = NET_EVENT_SOLDIER_MOVE_TO_ATTACK;
	eventinf.m_userID = userid;
	eventinf.m_infvec = infvec;
	return eventinf.execute();
}

bool CNetHandler::SendEventHeroSkill(int userid, int heroid, int skillid, const CCPoint& pt, int spec)
{
    _netSendEventHeroSkill eventinf;
    eventinf.m_eventType = NET_EVENT_HERO_SKILL;
    eventinf.m_userId = userid;
    eventinf.m_heroId = heroid;
    eventinf.m_skillId = skillid;
    eventinf.m_posX = pt.x;
    eventinf.m_posY = pt.y;
    eventinf.m_spec = spec;
    return eventinf.execute();
}

bool CNetHandler::SendEventSoldierDead(int userid,int soldierID)
{
	_netSendEventSoldierDead  eventinf;
	eventinf.m_eventType = NET_EVENT_SOLDIER_DEAD;
	eventinf.m_userID = userid;
	eventinf.m_soldierID = soldierID;
	return eventinf.execute();
}

//COCNET wwj
bool CNetHandler::SendEventBattleSearchPlayer(int userid, int userlevel, int userscore)
{
	_netSendEventBattleSearchPlayer eventinf;
	eventinf.m_eventType = NET_EVENT_SEARCH_BATTLE;
	eventinf.m_userID = userid;
	eventinf.m_userLevel = userlevel;
	eventinf.m_userScore = userscore;
	return eventinf.execute();
}

bool CNetHandler::SendEventSearchOnePlayer(int useid)
{
    _netSendEventSearchOnePlayer eventinf;
    eventinf.m_eventType = NET_EVENT_SEARCH_ONE_PLAYER;
    eventinf.m_userId = useid;
    return eventinf.execute();
}

bool CNetHandler::SendEventGetReplays(int userid, int attackid, int battleid)
{
	_netSendEventGetReplays eventinf;
	eventinf.m_eventType = NET_EVENT_GET_REPLAY_XML;
	eventinf.m_userID = userid;
	eventinf.m_attackID = attackid;
    eventinf.m_battleID = battleid;
	return eventinf.execute();
}

bool CNetHandler::SendEventAddBattleInfo(int defendid, int attackid, BattleInfo& info, const std::string& battleinfo)
{
	_netSendEventAddBattleInfo eventinf;
	eventinf.m_eventType = NET_EVENT_ADD_BATTLE_INFO;
	eventinf.m_defendId = defendid;
	eventinf.m_attackId = attackid;
    eventinf.m_attackScore = info.iScore;
	eventinf.m_deltaScore = info.iDeltaScore;
	eventinf.m_coin = info.iGoldNum;
	eventinf.m_food = info.iFoodNum;
    eventinf.m_union = info.unionName;
    eventinf.m_percent = info.iDamPer;
    eventinf.m_soldierType = 0;//info.iSoldierTypeNum;
    eventinf.m_star = info.iBattleStar;
    eventinf.m_battleState = info.state;
    eventinf.m_arrowManNum = info._mapNum[CMapObjectMgr::ARCHER].num;
    eventinf.m_arrowManLevel = info._mapNum[CMapObjectMgr::ARCHER].level;
    eventinf.m_footManNum = info._mapNum[CMapObjectMgr::MAGICIANS].num;
    eventinf.m_footManLevel = info._mapNum[CMapObjectMgr::MAGICIANS].level;
    eventinf.m_bombCatNum = info._mapNum[CMapObjectMgr::BOMBCATTLE].num;
    eventinf.m_bombCatLevel = info._mapNum[CMapObjectMgr::BOMBCATTLE].level;
    eventinf.m_thiefNum = info._mapNum[CMapObjectMgr::THIEF].num;
    eventinf.m_thiefLevel = info._mapNum[CMapObjectMgr::THIEF].level;
    eventinf.m_ironManNum = info._mapNum[CMapObjectMgr::CUIRASS].num;
    eventinf.m_ironManLevel = info._mapNum[CMapObjectMgr::CUIRASS].level;
    eventinf.m_doctorNum = info._mapNum[CMapObjectMgr::REMEDY].num;
    eventinf.m_doctorLevel = info._mapNum[CMapObjectMgr::REMEDY].level;
    eventinf.m_flyingNum = info._mapNum[CMapObjectMgr::FLYING].num;
    eventinf.m_flyingLevel = info._mapNum[CMapObjectMgr::FLYING].level;
    
	eventinf.m_battleData = battleinfo;
	return eventinf.execute();
}

bool CNetHandler::SendEventRevenge(int attackid, int defendid)
{
	_netSendEventRevenge eventinf;
	eventinf.m_eventType = NET_EVENT_REVENGE;
	eventinf.m_attackId = attackid;
	eventinf.m_defendId = defendid;
	return eventinf.execute();
}

bool CNetHandler::SendEventGetLatestReplays(int userid)
{
    _netSendEventGetLatestReplays eventinf;
    eventinf.m_eventType = NET_EVENT_GET_REPLAY_INFO;
	eventinf.m_userID = userid;
    return eventinf.execute();
}

bool CNetHandler::SendEventgetUserRanks(int userid)
{
    _netSendEventgetUserRanks eventinf;
    eventinf.m_eventType = NET_EVENT_RANK;
    eventinf.m_userId = userid;
    return eventinf.execute();
}

bool CNetHandler::SendEventGetSelectHeroTimes(int userid)
{
    _netSendEventGetSelectHeroTimes eventinf;
    eventinf.m_eventType = NET_EVENT_GET_SELECT_HERO_TIMES;
    eventinf.m_userId = userid;
    return eventinf.execute();
}

bool CNetHandler::SendEventSaveSelectHeroTiming(int userid, int hunLastTimes, std::string& hunPreTiming, int thouLastTimes, std::string& thouPreTiming)
{
    _netSendEventSaveSelectHeroTiming eventinf;
    eventinf.m_eventType = NET_EVENT_SAVE_SELECT_HERO_TIMING;
    eventinf.m_userId = userid;
    eventinf.m_hunLastTimes = hunLastTimes;
    eventinf.m_hunPreTimingStr = hunPreTiming;
    eventinf.m_thouLastTimes = thouLastTimes;
    eventinf.m_thouPreTimingStr = thouPreTiming;
    return eventinf.execute();
};

bool CNetHandler::SendEventUpdateSelectHeroTimes(int userid, int times)
{
    _netSendEventUpdateSelectHeroTimes eventinf;
    eventinf.m_eventType = NET_EVENT_UPDATE_SELECT_HERO_TIMES;
    eventinf.m_userId = userid;
    eventinf.m_heroTimes = times;
    return eventinf.execute();
}

//  [2013/6/28 12:31 butcher]
bool CNetHandler::SendEventKeepAlivePing()
{
	_netSendEventkeepAlivePing  eventinf;
	eventinf.m_eventType = NET_EVENT_KEEP_ALIVE_PING;
	return eventinf.execute();
}
bool CNetHandler::SendEventSaveMapAndBroadcast(int userid,const std::string& mapData)
{
	if(mapData.length() <= 0)
		return false;
	_netSendEventSaveMapAndBroadcast  eventinf;
	eventinf.m_eventType = NET_EVENT_SAVEMAPANDBROADCAST;
	eventinf.m_userID = userid;
	eventinf.m_mapdata = mapData;
	return eventinf.execute();
}
bool CNetHandler::SendEventReconnectServer(int m_userID)
{
	_netSendEventReconnectServer eventinf;
	eventinf.m_eventType = NET_EVENT_RECONNECT_SERVER;
	eventinf.m_userID = m_userID;
	return eventinf.execute();
}
///hsx 2013.10.21 系统时间
bool CNetHandler::SendSysTime()
{
    _netSendSysTime eventinf;
    eventinf.m_eventType = NET_EVENT_SYS_TIME;
	return eventinf.execute();
}